package com.zuipin.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.zuipin.entity.BalanceRecord;
import com.zuipin.entity.IntegralRecord;
import com.zuipin.entity.Member;
import com.zuipin.entity.MemberAccount;
import com.zuipin.entity.OrderConsignee;
import com.zuipin.entity.OrderDetail;
import com.zuipin.entity.OrderInfo;
import com.zuipin.entity.OrderInfoLog;
import com.zuipin.entity.OrderInvoiceInfo;
import com.zuipin.entity.PayLog;
import com.zuipin.entity.PayOrder;
import com.zuipin.entity.RedPacket;
import com.zuipin.entity.RuleSetUseLog;
import com.zuipin.enums.InvoiceType;
import com.zuipin.enums.OrderStatusEnum;
import com.zuipin.enums.PayMethod;
import com.zuipin.enums.PayType;
import com.zuipin.enums.SerialNumberEnum;
import com.zuipin.framework.emuns.ErrorCode;
import com.zuipin.framework.exception.CustomException;
import com.zuipin.framework.result.Result;
import com.zuipin.mapper.OrderConsigneeMapper;
import com.zuipin.mapper.OrderDetailMapper;
import com.zuipin.mapper.OrderInfoLogMapper;
import com.zuipin.mapper.OrderInfoMapper;
import com.zuipin.mapper.OrderInvoiceInfoMapper;
import com.zuipin.mapper.PayLogMapper;
import com.zuipin.mapper.PayOrderMapper;
import com.zuipin.service.IBalanceRecordService;
import com.zuipin.service.IGiftGivingService;
import com.zuipin.service.IIntegralRecordService;
import com.zuipin.service.IMemberAccountService;
import com.zuipin.service.IMemberService;
import com.zuipin.service.IPayOrderService;
import com.zuipin.service.IRedPacketService;
import com.zuipin.service.IRuleSetUseLogService;
import com.zuipin.util.ArithUtil;
import com.zuipin.util.Convert;
import com.zuipin.util.DateUtils;
import com.zuipin.util.HttpUtil;
import com.zuipin.util.RedisUtils;
import com.zuipin.util.StringUtil;
import com.zuipin.vo.ModityOrderUseStore;
import com.zuipin.vo.OrderDetailVo;
import com.zuipin.vo.PayOrderVo;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
public class PayOrderServiceImpl implements IPayOrderService {
	@Resource
	private PayOrderMapper			payOrderMapper;
	
	@Resource
	private OrderInfoMapper			orderInfoMapper;
	
	@Resource
	private OrderConsigneeMapper	orderConsigneeMapper;
	@Resource
	private OrderDetailMapper		orderDetailMapper;
	@Resource
	private OrderInvoiceInfoMapper	orderInvoiceInfoMapper;
	@Resource
	private OrderInfoLogMapper		orderInfoLogMapper;
	@Resource
	private RedisUtils				redisUtils;
	@Resource
	private PayLogMapper			payLogMapper;
	@Resource
	private IMemberService			memberService;
	@Resource
	private IRedPacketService		redPacketService;
	@Resource
	private IBalanceRecordService	balanceRecordService;
	@Resource
	private IRuleSetUseLogService	ruleSetUseLogService;
	
	@Resource
	private IGiftGivingService		giftGivingService;
	
	@Resource
	private IMemberAccountService	memberAccountService;
	
	@Resource
	private IIntegralRecordService	integralRecordService;
	
	protected final Logger			log	= Logger.getLogger(getClass());
	@Value("${cis.stockDealUrl}")
	private String					stockDealUrl;
	
	/**
	 * @Description:确认支付
	 * @Title:
	 * @author: xujinding
	 * @throws ParseException 
	 * @throws CustomException 
	 * @date: 2017年3月27日上午10:32:05
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
	public Result updateToPay(Long payId, Long sysUserId, Result res, String payMethod) throws CustomException {
		PayOrder oldPayOrder = payOrderMapper.selectByPrimaryKey(payId);
		// 确认支付--需求要求 在线支付 银行转账
		if (oldPayOrder != null) {
			List<OrderInfo> orderInfos = orderInfoMapper.findOrderListByPayId(oldPayOrder.getId());
			if (orderInfos != null && orderInfos.size() > 0) {
				OrderInfo orderInfo = orderInfos.get(0);
				if (OrderStatusEnum.待付款.getValue().equals(orderInfo.getOrderStatus())) {
					oldPayOrder.setConfimPayTime(DateUtils.getCurrentDateTime());
					oldPayOrder.setPayStatus(PayOrder.YES);
					oldPayOrder.setPayType(PayType.OFFLINE + "");
					oldPayOrder.setPayMethod(payMethod);
					oldPayOrder.setConfimSysUserId(sysUserId);
					oldPayOrder.setUpdateId(sysUserId);
					oldPayOrder.setUpdateTime(DateUtils.getCurrentDateTime());
					payOrderMapper.updateByPrimaryKeySelective(oldPayOrder);
					// 修改订单状态为付款成功待审核
					for (OrderInfo oi : orderInfos) {
						// 变成了在线支付
						oi.setOrderStatus(OrderStatusEnum.支付成功待审核.getValue());
						oi.setUpdateTime(DateUtils.getCurrentDateTime());
						orderInfoMapper.updateByPrimaryKeySelective(oi);
						OrderInfoLog orderInfoLog = new OrderInfoLog();
						orderInfoLog.setCreateTime(DateUtils.getCurrentDateTime());
						// orderInfoLog.setIpAddress(ip);
						// orderInfoLog.setDelFlag(BaseEntity.DEL_FLAG_YES);
						orderInfoLog.setSysUserId(sysUserId);
						orderInfoLog.setUpdateInfo("确认支付--修改订单状态：从待付款到待审核");
						orderInfoLog.setOrderNo(oi.getOrderNo());
						// orderInfoLog.setUpdateSrc((memberOrSystem.shortValue()));
						orderInfoLogMapper.insertSelective(orderInfoLog);
						// 赠送购物车---------------------------------------
						giftGivingService.doGiftGiving(oi.getId(), oi.getCreateMemberId(), oi.getSysId(), PayType.ONLINE, oi.getOrderNo());
					}
					
					res.setErrorCode(ErrorCode.SUCCESS);
				} else {
					res.setErrorCode(ErrorCode.ORDER_ERRPR);
					res.setMessage("只有订单在待付款才能支付确认");
				}
			} else {
				res.setErrorCode(ErrorCode.ORDER_ERRPR);
				res.setMessage("没有相应的订单");
			}
		} else {
			
			res.setErrorCode(ErrorCode.ORDER_ERRPR);
			res.setMessage("没有相应的付款单");
		}
		return res;
	}
	
	/**
	 * @Description:删除付款单
	 * @Title:
	 * @author: xujinding
	 * @throws CustomException 
	 * @date: 2017年3月27日上午10:32:05
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Result deleteToPay(Long payId, Result res) throws CustomException {
		PayOrder oldPayOrder = payOrderMapper.selectByPrimaryKey(payId);
		if (oldPayOrder != null) {
			List<OrderInfo> list = orderInfoMapper.findOrderListByPayId(oldPayOrder.getId());
			if (list != null && list.size() > 0) {
				for (OrderInfo oi : list) {
					if (OrderStatusEnum.已取消.getValue().equals(oi.getOrderStatus()) || OrderStatusEnum.订单完成.getValue().equals(oi.getOrderStatus())) {
						oi.setDelFlag(PayOrder.YES);
						// oi.setUpdateId(sysUserId);
						oi.setUpdateTime(DateUtils.getCurrentDateTime());
						orderInfoMapper.updateByPrimaryKeySelective(oi);
						// 订单详情不删--没影响
					} else {
						throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "只有取消订单或者订单完成才能删除订单");
					}
				}
				oldPayOrder.setDelFlag(PayOrder.YES);
				// oldPayOrder.setUpdateId(sysUserId);
				oldPayOrder.setUpdateTime(DateUtils.getCurrentDateTime());
				payOrderMapper.updateByPrimaryKeySelective(oldPayOrder);
				res.setErrorCode(ErrorCode.SUCCESS);
			} else {
				
				res.setErrorCode(ErrorCode.ORDER_ERRPR);
				res.setMessage("没有相应的订单");
			}
		} else {
			
			res.setErrorCode(ErrorCode.ORDER_ERRPR);
			res.setMessage("没有相应的付款单");
		}
		return res;
	}
	
	/**
	 * @Description:根据id查询付款单
	 * @Title:
	 * @author: xujinding
	 * @date: 2017年3月27日下午6:49:38
	 */
	@Override
	public PayOrder findPayOrderById(Long id) {
		PayOrder po = payOrderMapper.selectByPrimaryKey(id);
		return po;
		
	}
	
	/**
	 * 创建付款单 主订单 ，订单详情
	 * @throws ParseException 
	 * @throws Exception 
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result submitPayOrder(PayOrderVo payOrderVo) throws CustomException, ParseException {
		log.info("submitPayOrder:payOrderVo:=" + com.alibaba.fastjson.JSONObject.toJSONString(payOrderVo));
		Result result = new Result();
		// 是否是pc端。保存
		if (payOrderVo.getOrderDetails() == null || payOrderVo.getOrderDetails().size() <= 0) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "没有添加商品");
		}
		// 使用set来去重 验证数量是否一样 不一样代表重复
		// Set<OrderDetailVo> setDetailVo = new LinkedHashSet<OrderDetailVo>();
		// setDetailVo.addAll(payOrderVo.getOrderDetails());
		// setDetailVo.size();
		// if (setDetailVo.size() != payOrderVo.getOrderDetails().size()) {
		// throw new RuntimeException("商品重复，请检查参数");
		// }
		
		// 发票信息
		OrderInvoiceInfo orderInvoiceInfo = new OrderInvoiceInfo();
		orderInvoiceInfo.setDelFlag(PayOrder.NO);
		orderInvoiceInfo.setInvoiceContent(payOrderVo.getInvoiceContent());
		// orderInvoiceInfo.setUpdateId(payOrderVo.getCreateId());
		orderInvoiceInfo.setUpdateTime(DateUtils.getCurrentDateTime());
		// orderInvoiceInfo.setCreateId(payOrderVo.getCreateId());
		orderInvoiceInfo.setCreateTime(DateUtils.getCurrentDateTime());
		
		orderInvoiceInfo.setInvoiceType(payOrderVo.getInvoiceType());
		// 发票类型是个人 --抬头默认是个人
		if ((InvoiceType.NOT_INVOICE.toString()).equals(payOrderVo.getInvoiceType())) {
			orderInvoiceInfo.setInvoiceTitle(null);
		} else {
			if ((InvoiceType.COMPANY.toString()).equals(payOrderVo.getInvoiceTitle()) || (InvoiceType.PERSONAL.toString()).equals(payOrderVo.getInvoiceTitle())) {
				orderInvoiceInfo.setInvoiceTitle(payOrderVo.getInvoiceTitle());
			}
		}
		orderInvoiceInfo.setEmail(payOrderVo.getEmail());
		orderInvoiceInfo.setCompanyName(payOrderVo.getCompanyName());
		orderInvoiceInfo.setTaxpayersNo(payOrderVo.getTaxpayersNo());
		orderInvoiceInfo.setRegisterAddress(payOrderVo.getRegisterAddress());
		orderInvoiceInfo.setRegisterMobilePhone(payOrderVo.getRegisterMobilePhone());
		orderInvoiceInfo.setOpenAccount(payOrderVo.getOpenAccount());
		orderInvoiceInfo.setOpenBank(payOrderVo.getOpenBank());
		orderInvoiceInfo.setExpressStatus(OrderInvoiceInfo.STATUS_NO);
		orderInvoiceInfo.setInvoiceStatus(OrderInvoiceInfo.STATUS_NO);
		orderInvoiceInfoMapper.insertSelective(orderInvoiceInfo);
		// 付款单
		PayOrder payOrder = new PayOrder();
		payOrder.setIsUseStoreValue(PayOrder.NO);
		payOrder.setProductJfSum(payOrderVo.getProductJfSum() == null ? 0 : payOrderVo.getProductJfSum());
		payOrder.setCartRuleId(payOrderVo.getCartRuleId());
		payOrder.setDelFlag(PayOrder.NO);
		payOrder.setDevice(payOrderVo.getDevice());
		payOrder.setFreightSum(payOrderVo.getFreightSum() == null ? new BigDecimal(0.00) : payOrderVo.getFreightSum());
		payOrder.setOrderSum(payOrderVo.getOrderSum() == null ? new BigDecimal(0.00) : payOrderVo.getOrderSum());
		payOrder.setPayStatus(PayOrder.NO);
		payOrder.setCreateTime(DateUtils.getCurrentDateTime());
		payOrder.setCreateMemberId(payOrderVo.getCreateMemberId());
		payOrder.setUpdateTime(DateUtils.getCurrentDateTime());
		payOrder.setUseCashBackSum(payOrderVo.getUseCashBackSum() == null ? new BigDecimal(0.00) : payOrderVo.getUseCashBackSum());
		payOrder.setUseJfSum(payOrderVo.getUseJfSum() == null ? 0 : payOrderVo.getUseJfSum());
		payOrder.setGiveJfSum(payOrderVo.getGiveJfSum() == null ? 0 : payOrderVo.getGiveJfSum());
		payOrder.setGiveCashBackSum(payOrderVo.getGiveCashBackSum() == null ? new BigDecimal(0.00) : payOrderVo.getGiveCashBackSum());
		payOrder.setUseStoreValue(payOrderVo.getUseStoreValue() == null ? new BigDecimal(0.00) : payOrderVo.getUseStoreValue());
		payOrder.setUseRedPacketSum(payOrderVo.getUseRedPacketSum() == null ? new BigDecimal(0.00) : payOrderVo.getUseRedPacketSum());
		payOrder.setRedPacketName(payOrderVo.getRedPacketName());
		payOrder.setUseRedPacketId(payOrderVo.getUseRedPacketId());
		payOrder.setSysId(payOrderVo.getSysId());
		payOrder.setIsSplitOrder(PayOrder.NO);
		payOrder.setTotalWeight(payOrderVo.getTotalWeight());
		payOrder.setInvoiceInfoId(orderInvoiceInfo.getId());
		payOrder.setIsBrushOrder(payOrderVo.getIsBrushOrder());
		payOrder.setVersionFreight(0L);// 刚创建 只为0
		payOrder.setPayType(payOrderVo.getPayType());
		payOrder.setProductPaySum(payOrderVo.getProductPaySum() == null ? new BigDecimal(0.00) : payOrderVo.getProductPaySum());
		payOrder.setUseRuleSum(payOrderVo.getUseRuleDiscountSum());
		payOrderMapper.insertSelective(payOrder);
		
		// 保存收货地址
		OrderConsignee orderConsignee = new OrderConsignee();
		orderConsignee.setCreateTime(DateUtils.getCurrentDateTime());
		orderConsignee.setUpdateTime(DateUtils.getCurrentDateTime());
		orderConsignee.setReceiptName(payOrderVo.getReceiptName());
		orderConsignee.setPhone(payOrderVo.getPhone());
		orderConsignee.setTelephone(payOrderVo.getTelephone());
		orderConsignee.setStreetAddress(payOrderVo.getStreetAddress());
		orderConsignee.setAddress(payOrderVo.getAddress());
		orderConsignee.setCityCode(payOrderVo.getCityCode());
		orderConsignee.setCountyCode(payOrderVo.getCountyCode());
		orderConsignee.setProvinceCode(payOrderVo.getProvinceCode());
		orderConsigneeMapper.insertSelective(orderConsignee);
		
		// 主订单
		OrderInfo orderInfo = new OrderInfo();
		orderInfo.setProductJfSum(payOrder.getProductJfSum() == null ? 0 : payOrder.getProductJfSum());
		orderInfo.setInvoiceInfoId(orderInvoiceInfo.getId());
		orderInfo.setFreightSum(payOrder.getFreightSum() == null ? new BigDecimal(0.00) : payOrder.getFreightSum());
		orderInfo.setDelFlag(PayOrder.NO);
		orderInfo.setCreateMemberId(payOrderVo.getCreateMemberId());
		orderInfo.setCreateId(payOrder.getCreateId());
		orderInfo.setUseStoreValue(payOrder.getUseStoreValue() == null ? new BigDecimal(0.00) : payOrder.getUseStoreValue());
		orderInfo.setCreateTime(DateUtils.getCurrentDateTime());
		orderInfo.setUpdateTime(DateUtils.getCurrentDateTime());
		orderInfo.setExpressDeliveryName(payOrderVo.getExpressDeliveryName());
		orderInfo.setExpressDeliveryCode(payOrderVo.getExpressDeliveryCode());
		orderInfo.setUseJfSum(payOrderVo.getUseJfSum() == null ? 0 : payOrderVo.getUseJfSum());
		orderInfo.setGiveJfSum(payOrderVo.getGiveJfSum() == null ? 0 : payOrderVo.getGiveJfSum());
		orderInfo.setGiveCashBackSum(payOrderVo.getGiveCashBackSum() == null ? new BigDecimal(0.00) : payOrderVo.getGiveCashBackSum());
		orderInfo.setUseCashBackSum(payOrderVo.getUseCashBackSum() == null ? new BigDecimal(0.00) : payOrderVo.getUseCashBackSum());
		String orderNo = redisUtils.getSerialNumber(SerialNumberEnum.主订单);
		orderInfo.setOrderNo(orderNo);
		log.info("new orderNo :" + orderInfo.getOrderNo());
		orderInfo.setOrderSum(payOrderVo.getOrderSum() == null ? new BigDecimal(0.00) : payOrderVo.getOrderSum());
		orderInfo.setBuyerId(000000000000l);
		orderInfo.setTotalWeight(payOrderVo.getTotalWeight());
		if ((PayType.CASH_DELIVERY + "").equals(payOrder.getPayType())) {
			orderInfo.setOrderStatus(OrderStatusEnum.待审核.getValue());
		} else {
			orderInfo.setOrderStatus(OrderStatusEnum.待付款.getValue());
		}
		orderInfo.setCustomerRemark(payOrderVo.getCustomerRemark());
		orderInfo.setOrderRemark(payOrderVo.getOrderRemark());
		orderInfo.setSysId(payOrderVo.getSysId());
		orderInfo.setConsigneeId(orderConsignee.getId());
		orderInfo.setPaymentOrderId(payOrder.getId());
		orderInfo.setProductPaySum(payOrderVo.getProductPaySum() == null ? new BigDecimal(0.00) : payOrderVo.getProductPaySum());
		orderInfo.setGrowthValue(payOrderVo.getGrowthValue());
		orderInfo.setCreateId(payOrderVo.getCreateId());
		orderInfo.setUpdateId(payOrderVo.getCreateId());
		orderInfo.setIsGiveGrowthValue(OrderInfo.IS_GIVE_GROWTH_VALUE_NO_0);
		orderInfo.setUseRuleSum(payOrderVo.getUseRuleDiscountSum());
		orderInfoMapper.insertSelective(orderInfo);
		
		// 插入购物车使用规则ID
		if (payOrderVo.getRuleSetUseLogs() != null && payOrderVo.getRuleSetUseLogs().size() > 0) {
			for (RuleSetUseLog ruleSetUseLog : payOrderVo.getRuleSetUseLogs()) {
				ruleSetUseLog.setOrderId(orderInfo.getId());
				ruleSetUseLogService.insert(ruleSetUseLog);
			}
		}
		
		OrderInfoLog orderInfoLog = new OrderInfoLog();
		orderInfoLog.setCreateTime(DateUtils.getCurrentDateTime());
		// orderInfoLog.setIpAddress(ip);
		// orderInfoLog.setDelFlag(BaseEntity.DEL_FLAG_YES);
		orderInfoLog.setSysUserId(payOrderVo.getCreateId());
		if (payOrderVo.getIsFromBack() != null && PayOrderVo.IS_FROM_BACK_YES_1 == payOrderVo.getIsFromBack()) {
			orderInfoLog.setUpdateInfo("操作人(ID=" + payOrderVo.getCreateId() + ")操作后台生成订单");
		} else {
			orderInfoLog.setUpdateInfo("生成订单");
		}
		orderInfoLog.setOrderNo(orderInfo.getOrderNo());
		orderInfoLog.setMemberId(payOrderVo.getCreateMemberId());
		// orderInfoLog.setUpdateSrc((memberOrSystem.shortValue()));
		orderInfoLogMapper.insertSelective(orderInfoLog);
		
		RedPacket redPacket = new RedPacket();
		redPacket.setId(payOrder.getUseRedPacketId());
		redPacket.setStatus(com.zuipin.enums.RedPackStatus.USED);
		redPacket.setOrderNo(orderNo);
		redPacket.setOrderId(orderInfo.getId());
		redPacketService.update(redPacket);
		// 使用积分
		integralRecordService.addIntegralRecord(payOrder.getCreateMemberId(), payOrder.getSysId(), null, null, -1 * payOrder.getUseJfSum(),
				com.zuipin.enums.IntegralType.USE_SHOPPING, "积分兑换", "订单号", orderInfo.getOrderNo(), IntegralRecord.IS_BUY_YES);
		/*		balanceRecordService.updateBalance(payOrder.getCreateMemberId(), payOrder.getSysId(), payOrder.getCreateMemberId(), payOrder.getCreateMemberId(),
						ArithUtil.mul(payOrder.getUseStoreValue(), new BigDecimal(-1)), com.zuipin.enums.BalanceType.BUY_USE, "购物使用充值");*/
		// 拼接商品编号
		/*		String proNos = "";
				for (int i = 0; i < payOrderVo.getOrderDetails().size(); i++) {
					if (i == payOrderVo.getOrderDetails().size() - 1) {
						proNos = proNos + payOrderVo.getOrderDetails().get(i).getProSku();
					} else {
						proNos = proNos + payOrderVo.getOrderDetails().get(i).getProSku() + ",";
					}
				}*/
		// 获取并验证库存
		// -System.out.println(proNos);
		// Map<String, JSONObject> map = findCisBranchStockByProNo(proNos);
		// 订单详情
		List<OrderDetail> orderDetails = new ArrayList<OrderDetail>();
		for (OrderDetailVo vo : payOrderVo.getOrderDetails()) {
			// 验证库存
			// boolean stockFlag = this.checkStock(vo.getProductNo(), vo.getProductNum(), map);
			// if (!stockFlag) {
			// throw new RuntimeException("库存不足或者没有该商品");
			// }
			
			OrderDetail od = new OrderDetail();
			od.setOrderId(orderInfo.getId());
			od.setCreateTime(DateUtils.getCurrentDateTime());
			od.setPremiumEnum((vo.getPremiums()));
			od.setJfPrice(vo.getJfPrice() == null ? 0 : vo.getJfPrice());
			od.setDelFlag(PayOrder.NO);
			od.setUpdateTime(DateUtils.getCurrentDateTime());
			od.setPackNo(vo.getPackNo());
			od.setProductName(vo.getProductName());
			od.setProductNum(vo.getProductNum());
			od.setProSku(vo.getProSku());
			od.setPurchasePrice(vo.getPurchasePrice() == null ? new BigDecimal(0.00) : vo.getPurchasePrice());
			od.setProductProperty(vo.getProductProperty());
			od.setProductPrice(vo.getProductPrice() == null ? new BigDecimal(0.00) : vo.getProductPrice());
			od.setPackWeight(vo.getPackWeight());
			od.setSubtotal(vo.getSubtotal() == null ? new BigDecimal(0.00) : vo.getSubtotal());
			od.setSupplierId(vo.getSupplierId());
			od.setUseCashBackSum(vo.getUseCashBackSum() == null ? new BigDecimal(0.00) : vo.getUseCashBackSum());
			od.setUseJfSum(vo.getUseJfSum() == null ? 0 : vo.getUseJfSum());
			od.setGiveJfSum(vo.getGiveJfSum() == null ? 0 : vo.getGiveJfSum());
			od.setGiveCashBackSum(vo.getGiveCashBackSum() == null ? new BigDecimal(0.00) : vo.getGiveCashBackSum());
			od.setBusinessType(vo.getBusinessType());
			od.setUseRedPacketSum(vo.getUseRedPacketSum() == null ? new BigDecimal(0.00) : vo.getUseRedPacketSum());
			od.setUseRuleSum(vo.getUseRuleSum());
			od.setActualPaySubtotal(vo.getActualPaySubtotal());
			od.setRuleShowName(vo.getRuleName());
			od.setRuleId(vo.getRuleSetId());
			od.setJfPurchasePrice(vo.getJfPurchasePrice() == null ? new BigDecimal(0.00) : vo.getJfPurchasePrice());
			od.setJfSubtotal(vo.getJfSubtotal());
			if (vo.getIsJfProduct() != null) {
				od.setIsJfProduct(vo.getIsJfProduct());
			} else {
				od.setIsJfProduct(OrderDetail.IS_JF_PRODUCT_NO);
			}
			orderDetailMapper.insertSelective(od);
			orderDetails.add(od);
		}
		
		// 虚拟预占
		Member member = memberService.findById(orderInfo.getCreateMemberId());
		if (member == null) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "查询不到下单人员");
		}
		boolean isHoldSuccess = this.preholdCisStock(orderDetails, PayOrder.PRE_HOLD_STOCK, orderInfo, "下单预占虚拟库存", member.getContactName() + "", null);
		if (!isHoldSuccess) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "预占库存失败，请检查商品在库存系统中是否存在");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("payId", payOrder.getId());
		map.put("orderSum", payOrder.getOrderSum());
		map.put("versionFreight", payOrder.getVersionFreight());
		map.put("orderId", orderInfo.getId());
		map.put("orderNo", orderInfo.getOrderNo());
		map.put("payType", payOrder.getPayType());
		result.setData(map);
		return result;
	}
	
	/**
	 * 根据商品编号查询商品分仓库存
	 * 
	 * @Title: ICommodityService
	 * @param: @param showId
	 * @author:xujinding
	 * @return: Stock
	 * @throws:
	 * @Description: TODO
	 */
	public Map<String, JSONObject> findCisBranchStockByProNo(String proNos) {
		log.info("同步商品参数" + proNos);
		Map<String, JSONObject> returnMap = new HashMap<String, JSONObject>();
		try {
			StringBuffer url = new StringBuffer();
			// PropertiesManager propertiesManager = SpringContextHolder.getBean("propertiesManager");
			// url.append(propertiesManager.getString("cis_url"));
			// url.append(propertiesManager.getString("cis_findBranchStock"));
			url.append("&proNo=" + proNos);
			log.info(url.toString());
			String cisResult = HttpUtil.post(url.toString(), null, 0, 0);
			log.info("同步cis的还回值" + cisResult);
			JSONObject returnParam = JSONObject.fromObject(cisResult);
			boolean flags = returnParam.getBoolean("success");
			if (flags) {
				JSONArray pros = returnParam.getJSONArray("stockInfo");
				if (pros != null && pros.size() > 0) {
					for (int i = 0; i < pros.size(); i++) {
						Double nowStock = 0.0;
						Double disableQty = 0.0;
						Double supStock = 0.0;
						JSONObject pro = pros.getJSONObject(i);
						String proNo = pro.getString("proNo");
						Integer isTea = 0;
						try {
							disableQty = pro.getDouble("inventDisableQty");// 领料预占
							isTea = pro.getInt("isTea");
						} catch (Exception e) {
							log.info("这两个只有在cis有这个商品时才出参，没有的话就当做职位0");
						}
						try {
							supStock = pro.getDouble("supplierStock");// 供应商库存
						} catch (Exception e) {
							log.info("供应商库存  只有 接口有配置才出参");
						}
						JSONArray repertoryInfos = pro.getJSONArray("repertoryInfo");
						if (repertoryInfos != null && repertoryInfos.size() > 0) {
							for (int j = 0; j < repertoryInfos.size(); j++) {
								JSONObject repertoryInfo = repertoryInfos.getJSONObject(j);
								Double tempNormalQty = repertoryInfo.getDouble("normalQty");
								Double tempLockQty = repertoryInfo.getDouble("lockQty");
								nowStock = nowStock + tempNormalQty - tempLockQty;
							}
						}
						nowStock = nowStock - disableQty;
						JSONObject json = new JSONObject();
						json.put("nowStock", nowStock < 0 ? 0.0 : nowStock);
						json.put("supStock", supStock);
						json.put("isTea", isTea);
						json.put("proNo", proNo);
						returnMap.put(proNo, json);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.info(e.getMessage());
		}
		return returnMap;
	}
	
	/**
	 *库存不足或者没有库存返回false
	* @Description:校验库存
	* @Title: 
	* @author: xujinding
	* @date: 2017年4月1日下午6:02:17
	 */
	public boolean checkStock(String proNo, BigDecimal buyNum, Map<String, JSONObject> map) {
		JSONObject jsob = map.get(proNo);
		if (jsob != null) {
			
			BigDecimal nowStock = jsob.get("nowStock") == null ? BigDecimal.valueOf(0.00) : new BigDecimal(String.valueOf(jsob.get("nowStock")));
			BigDecimal supStock = jsob.get("supStock") == null ? BigDecimal.valueOf(0.00) : new BigDecimal(String.valueOf(jsob.get("supStock")));
			
			// jsob.get("isTea");
			BigDecimal stockNum = ArithUtil.add(nowStock, supStock);
			if (stockNum.doubleValue() < buyNum.doubleValue()) {
				return false;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}
	
	/**
	 * 发送MQ消息 1 预占商品库存 2 释放商品库存预占
	 * 
	 * @Title: OrderServiceImpl
	 * @param: @param OrderInfo
	 * @param: @param Member
	 * @param: @param ShoppingCart
	 * @param: @param flag
	 * @return:
	 * @throws:
	 * @author xujinding
	 * @Description: TODO
	 */
	public boolean preholdCisStock(List<OrderDetail> orderDetail, int flag, OrderInfo orderInfo, String remark, String worker, Short isALLRelease) {
		String url = "";
		boolean isHoldSuccess = false;
		JSONArray jsonArray = new JSONArray();
		for (OrderDetail od : orderDetail) {
			JSONObject json = new JSONObject();
			json.put("proNo", od.getProSku());// 商品编码
			json.put("repId", -2);// 仓库id
			
			json.put("qtyChange", 0);// 可用库存变更
			json.put("tranyChange", 0);// 在途库存变更
			json.put("lockChange", 0);// 真实预占库存变更
			// 单据类型 ZZD(组装单)、LL(领料单)、CX（拆卸单）、XSD（销售订单）、DB（调拨单）、CGRK（采购入库单）、CGTH（采购退货单）、XXTH（销售退货单）、PD（盘点单）、KCXY（库存差异调整）
			json.put("billType", PayOrder.XSD);
			json.put("billNO", orderInfo.getOrderNo());// 单据编号
			
			json.put("worker", worker);// 操作人的Id
			json.put("workTime", DateUtils.getCurrentDateTime());// 操作时间
			if (OrderInfo.ZP_SYS_ID.equals(orderInfo.getSysId())) {
				json.put("billCome", 4);// 系统来源 0（ERP）、1（GYS）、2（CBT）、3（WMS）、4（ZP）
			}
			if (flag == PayOrder.PRE_HOLD_STOCK) {// 库存预占
				json.put("falseLockChange", od.getProductNum());// 虚拟预占库存变更
				json.put("remark", remark);// 备注
			} else if (flag == PayOrder.PRE_RELEASE_STOCK) {// 库存释放
				json.put("falseLockChange", od.getProductNum().multiply(new BigDecimal(-1)));// 虚拟预占库存变更
				json.put("remark", remark);// 备注
				// isALLRelease 1整单 0 根据商品
				json.put("isALLRelease", isALLRelease);
			}
			jsonArray.add(json);
		}
		if (jsonArray.size() > 0) {
			// 参数有特殊符号替换掉
			// [\\s~·`!！@￥$^……*（()）\\-——\\-_=+【\\[\\]】｛{}｝\\|、\\\\；;：:‘'“”\"，,《<。.》>、/？?]
			String newStr = jsonArray.toString().replaceAll("&", "").replaceAll("%", "").replaceAll("#", "");
			log.info("到cis预占库存参数：：" + newStr);
			String str = HttpUtil.post(stockDealUrl, "requestData", newStr);
			log.info("cis返回值：：：" + str);
			if (!StringUtil.isBlank(str)) {
				JSONObject jobj = JSONObject.fromObject(str);
				if (jobj != null && jobj.get("success") != null && jobj.getBoolean("success")) {
					isHoldSuccess = true;
				}
			}
		}
		return isHoldSuccess;
		
	}
	
	/**
	 * 
	* @Description:
	* @Title: 
	* @author: xujinding
	* @date: 2017年4月5日下午4:09:54
	 */
	@Override
	public void savePayLog(String payMethod, BigDecimal realPay, Long payId, String remark, String backParameter) {
		PayLog payLog = new PayLog();
		payLog.setRealPay(realPay);
		payLog.setCreateTime(DateUtils.getCurrentDateTime());
		payLog.setPaymengId(payId);
		payLog.setRemark(remark);
		payLog.setCallBackSrc(payMethod + "");
		payLog.setBackParameter(backParameter);
		payLog.setCallBackResult("");
		payLogMapper.insertSelective(payLog);
	}
	
	/**
	 *
	* @Description:支付成功更新状态  cashFee 单位元
	* @Title: 
	* @author: xujinding
	* @date: 2017年4月5日下午6:02:17
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
	public Result updatePayState(String payNo, String cashFee, String result, String payMethod) {
		// 是否成功完成修改状态记录日志等操作
		Result res = new Result();
		if (payNo != null) {
			Long payId = null;
			payId = getPayId(payNo);
			PayOrder payOrder = payOrderMapper.selectByPrimaryKey(payId);
			String dec = "payNo::" + payNo + "==";
			if (payOrder != null && !(PayOrder.YES.equals(payOrder.getPayStatus())) && (PayType.ONLINE + "").equals(payOrder.getPayType())) {
				if (payOrder.getOrderSum().doubleValue() == Double.parseDouble(cashFee)) {
					payOrder.setPayStatus(PayOrder.YES);
					payOrder.setConfimPayTime(DateUtils.getCurrentDateTime());
					payOrder.setPayType(PayType.ONLINE + "");
					payOrder.setUpdateTime(DateUtils.getCurrentDateTime());
					payOrder.setPayMethod(payMethod);
					// 支付方式
					payOrderMapper.updateByPrimaryKeySelective(payOrder);
					// 修改订单状态为待审核
					List<OrderInfo> orderInfos = orderInfoMapper.findOrderListByPayId(payOrder.getId());
					for (OrderInfo oi : orderInfos) {
						oi.setOrderStatus(OrderStatusEnum.支付成功待审核.getValue());
						oi.setUpdateTime(DateUtils.getCurrentDateTime());
						orderInfoMapper.updateByPrimaryKeySelective(oi);
						OrderInfoLog orderInfoLog = new OrderInfoLog();
						orderInfoLog.setCreateTime(DateUtils.getCurrentDateTime());
						orderInfoLog.setUpdateInfo("在线支付回调确认支付--修改订单状态：从待付款到待审核");
						orderInfoLog.setOrderNo(oi.getOrderNo());
						orderInfoLogMapper.insertSelective(orderInfoLog);
						// 赠送购物车---------------------------------------
						try {
							giftGivingService.doGiftGivingByPay(oi.getId(), oi.getCreateMemberId(), oi.getSysId(), PayType.ONLINE, oi.getOrderNo());
						} catch (Exception e) {
							log.info("购物车规则赠送失败了" + e.toString());
						}
					}
					dec = dec + "支付成功更新状态";
					log.info("payNo::" + payNo + dec);
					res.setErrorCode(ErrorCode.SUCCESS);
					
				} else {
					dec = dec + "金额不匹配实际支付了：" + Double.parseDouble(cashFee) + ",但是订单金额：" + payOrder.getOrderSum().doubleValue();
					log.info("payNo::" + payNo + dec);
					res.setErrorCode(ErrorCode.ORDER_ERRPR);
					res.setMessage("金额不匹配");
				}
			} else {
				if (payOrder == null) {
					res.setErrorCode(ErrorCode.ORDER_ERRPR);
					res.setMessage("查无此付款单");
					log.info("查无此付款单:payNo=" + payNo);
					dec = dec + "查无此付款单";
				} else if (PayOrder.YES.equals(payOrder.getPayStatus())) {
					log.info("已支付，重复回调::payNo=" + payNo);
					dec = dec + "已支付--重复回调";
					res.setErrorCode(ErrorCode.ORDER_ERRPR);
					res.setMessage("已支付--重复回调");
				} else if (!((PayType.ONLINE + "").equals(payOrder.getPayType()))) {
					log.info("只有在线支付的才能回调::payNo=" + payNo);
					dec = dec + "只有在线支付的才能回调";
					res.setErrorCode(ErrorCode.ORDER_ERRPR);
					res.setMessage("只有在线支付的才能回调");
				}
			}
			this.savePayLog(payMethod, new BigDecimal(cashFee), payId, dec, result);
		} else {
			res.setErrorCode(ErrorCode.ORDER_ERRPR);
			res.setMessage("参数有误");
		}
		return res;
	}
	
	/**
	 * 
	* @Description:
	* @Title: 
	* @author: xujinding
	* @date: 2017年4月7日下午4:40:31
	 */
	@Override
	public Long getPayId(String payNo) {
		Long payId = null;
		if (payNo != null) {
			if (payNo.indexOf("_") != -1) {
				// 去掉版本号
				String[] payStr = payNo.split("_");
				payId = Long.valueOf(payStr[0]);
			} else {
				payId = Long.valueOf(payNo);
			}
		}
		return payId;
	}
	
	/** 
	 * 获取每个商品详情优惠价
	 * 
	 * @Title: getUseDiscountAmount 
	 * @author: wuyicheng
	 * @date: 2017年6月20日下午6:30:22 
	 * @param subtotal
	 * @param proTotalAmount
	 * @param discountAmount
	 * @return
	 * @throws 
	 */
	@Override
	public BigDecimal getUseDiscountAmount(BigDecimal subtotal, BigDecimal proTotalAmount, BigDecimal discountAmount) {
		if (ArithUtil.compareTo(proTotalAmount, BigDecimal.ZERO) != 0) {
			BigDecimal subtotalRatio = ArithUtil.div(subtotal, proTotalAmount, 6);
			BigDecimal useDiscountAmount = ArithUtil.mul(subtotalRatio, discountAmount, 2);
			return useDiscountAmount;
		}
		return new BigDecimal(0.00);
	}
	
	@Override
	public ModityOrderUseStore modityOrderStoreValue(String orderNo, Long sysId, Long memberId, BigDecimal useStoreValue) throws CustomException {
		
		if (StringUtil.isBlank(orderNo)) {
			throw new CustomException(ErrorCode.ILLEGAL_PARAM.getCode(), "订单编码为空");
		}
		
		/*		Map<String, Object> paMap = new HashMap<String, Object>();
				paMap.put("orderNo", orderNo);
				paMap.put("memberId", memberId);
				Map<String, Object> map = orderInfoMapper.getOrderAndPayInfoByOrderNo(paMap);*/
		
		OrderInfo oi = orderInfoMapper.findOrderInfoByOrderNo(orderNo);
		if (oi == null || !oi.getCreateMemberId().equals(memberId)) {
			throw new CustomException(ErrorCode.NOT_FIND.getCode(), "订单不存在");
		}
		/*		if (!oi.getCreateMemberId().equals(memberId)) {
					throw new CustomException(ErrorCode.ORDER_NOT_OWNER.getCode(), "订单不是你的");
				}
				*/
		Member member = memberService.findById(oi.getCreateMemberId());
		
		if (member == null) {
			throw new CustomException(ErrorCode.MEMBER_NOT_EXIST.getCode(), "会员不存在");
		}
		
		PayOrder po = payOrderMapper.selectByPrimaryKey(oi.getPaymentOrderId());
		if (po == null) {
			throw new CustomException(ErrorCode.NOT_FIND.getCode(), "付款单不存在");
		}
		
		Double orderSum = po.getOrderSum().doubleValue();// 订单金额
		if (orderSum <= 0) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "订单不需要支付");
		}
		
		if (!(OrderStatusEnum.待付款.getValue().equals(oi.getOrderStatus()) || OrderStatusEnum.待审核.getValue().equals(oi.getOrderStatus()))) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "只有待付款或待审核订单才能进行此操作");
		}
		
		if (PayOrder.YES.equals(Convert.toShort(po.getIsUseStoreValue()))) {
			throw new CustomException(ErrorCode.ORDER_ERRPR.getCode(), "该订单已经使用过余额");
		}
		
		MemberAccount userAccount = new MemberAccount();
		userAccount.setMemberId(member.getId());
		userAccount.setSysId(sysId);
		MemberAccount memberAccount = memberAccountService.findByMemberAccount(userAccount);
		if (memberAccount == null) {
			throw new CustomException(ErrorCode.MEMBER_NOT_EXIST.getCode(), "会员账户不存在");
		}
		
		BigDecimal totalAmount = memberAccount.getTotalAmount();
		if (totalAmount == null || !(totalAmount.doubleValue() > 0)) {
			throw new CustomException(ErrorCode.TOTAL_AMOUNT_OUT_OF.getCode(), "余额不足，请前往充值");
		}
		
		if (totalAmount.doubleValue() >= orderSum) {
			// 订单相当已支付
			po.setUseStoreValue(po.getOrderSum());
			po.setOrderSum(new BigDecimal(0.00));
			po.setIsUseStoreValue(PayOrder.YES);
			po.setVersionFreight(po.getVersionFreight() + 1L);
			po.setPayStatus(PayOrder.YES);
			po.setConfimPayTime(DateUtils.getCurrentDateTime());
			po.setPayType(PayType.ONLINE + "");
			po.setUpdateTime(DateUtils.getCurrentDateTime());
			po.setPayMethod(PayMethod.STORE_VALUE_PAY + "");
			// 支付方式
			payOrderMapper.updateByPrimaryKeySelective(po);
			oi.setOrderSum(new BigDecimal(0.00));
			oi.setUseStoreValue(po.getUseStoreValue());
			oi.setOrderStatus(OrderStatusEnum.支付成功待审核.getValue());
			oi.setUpdateTime(DateUtils.getCurrentDateTime());
			orderInfoMapper.updateByPrimaryKeySelective(oi);
			balanceRecordService.updateBalance(po.getCreateMemberId(), po.getSysId(), null, null, ArithUtil.mul(new BigDecimal(-1), po.getUseStoreValue()),
					com.zuipin.enums.BalanceType.BUY_USE, "消费", "订单号", oi.getOrderNo(), BalanceRecord.IS_BUY_YES);
			// 赠送购物车---------------------------------------
			giftGivingService.doGiftGiving(oi.getId(), oi.getCreateMemberId(), oi.getSysId(), PayType.ONLINE, oi.getOrderNo());
		} else {
			// 改变实付
			po.setOrderSum(ArithUtil.sub(po.getOrderSum(), totalAmount));
			po.setUseStoreValue(totalAmount);
			po.setIsUseStoreValue(PayOrder.YES);
			po.setVersionFreight(po.getVersionFreight() + 1L);
			payOrderMapper.updateByPrimaryKeySelective(po);
			oi.setUseStoreValue(totalAmount);
			oi.setOrderSum(po.getOrderSum());
			oi.setUpdateTime(DateUtils.getCurrentDateTime());
			orderInfoMapper.updateByPrimaryKeySelective(oi);
			balanceRecordService.updateBalance(po.getCreateMemberId(), po.getSysId(), null, null, ArithUtil.mul(new BigDecimal(-1), po.getUseStoreValue()),
					com.zuipin.enums.BalanceType.BUY_USE, "消费", "订单号", oi.getOrderNo(), BalanceRecord.IS_BUY_YES);
			
		}
		OrderInfoLog orderInfoLog = new OrderInfoLog();
		orderInfoLog.setCreateTime(DateUtils.getCurrentDateTime());
		// orderInfoLog.setIpAddress(ip);
		orderInfoLog.setMemberId(oi.getCreateMemberId());
		orderInfoLog.setSysUserId(null);
		orderInfoLog.setUpdateInfo("支付时选择使用充值修改了订单金额");
		orderInfoLog.setOrderNo(oi.getOrderNo());
		orderInfoLogMapper.insertSelective(orderInfoLog);
		ModityOrderUseStore mous = new ModityOrderUseStore();
		mous.setOrderId(oi.getId());
		mous.setPayId(oi.getPaymentOrderId());
		mous.setOrderSum(po.getOrderSum());
		mous.setPayType(po.getPayType());
		mous.setVersionFreight(po.getVersionFreight());
		mous.setOrderNo(oi.getOrderNo());
		mous.setStoreValue(po.getUseStoreValue());
		mous.setPayMethod(po.getPayMethod());
		return mous;
	}
}
